#include <fstream>
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include "Serializer.h"

#define foreach BOOST_FOREACH

using namespace boost::gregorian;
using namespace boost::filesystem;
using namespace kc_sf;

// ------------------------------------------------------------ //

Serializer::Serializer( const std::string &dir_path, const RawMessage &rmsg )
: s_root_path( dir_path ),
  s_raw_message( rmsg )
{
}

// ------------------------------------------------------------ //

std::string Serializer::operator ()()
{
	// tworze katalog wiadomosci z dnia (rrrrmmdd)
	std::string date = to_iso_string( s_raw_message.rmCameDate.date() );

	path dir( s_root_path + "/" + date );

	if( !exists( dir ) && !create_directory( dir ) ) // tworzymy katalog
	{
		s_logger << error << archiver << mid( s_raw_message.Id ) << "Nie udało się utworzyć podkatalogu do przechowywania wiadomosci" << flush;
		return "";
	}

	// tworze pliki

	// znaczek czasowy (ggmmssuu)
	std::string time = to_iso_string( s_raw_message.rmCameDate.time_of_day() );
	// potrzebujemy tylko msec
	size_t comma = time.find( ',' );
	if( comma != std::string::npos )
	{
		std::string miliseconds = time.substr( comma + 1, 2 );
		time = time.substr( 0, comma );
		time += miliseconds;
	}

	std::string message_filepath = dir.string() + "/" + time + ".msg";
	std::string envelope_filepath = message_filepath + ".env";

    // jeśli plik istnieje zostanie nadpisany
	std::ofstream message_ofstream( message_filepath.c_str() , std::ios::trunc );
	std::ofstream envelope_ofstream( envelope_filepath.c_str() , std::ios::trunc );

    if( !message_ofstream.is_open() )
    {
		s_logger << error << archiver << mid( s_raw_message.Id ) << "Nie udało się otworzyć pliku wiadomosci " << message_filepath << flush;
		return "";
    }

    message_ofstream << s_raw_message.rmData;

    if( !envelope_ofstream.is_open() )
    {
		s_logger << error << archiver << mid( s_raw_message.Id ) << "Nie udało się otworzyć pliku koperty " << envelope_filepath << flush;
		return "";
    }

    envelope_ofstream << s_raw_message.rmMailFrom.toString() << std::endl;

    foreach( Address rcpt, s_raw_message.rmRcptsTo )
    {
    	envelope_ofstream << rcpt.toString() << std::endl;
    }

	return message_filepath;
}
